;------------------------------------------------------------------------------
;Program:  scxtl.asm
;Author :  Wouter Caarls, Delft University of Technology
;Task   :  SmartCam XeTaL1 coprocessor program
;Works  :  By task scheduling a number of operations, which read from 
;       :  indirected line memories. Tasks can be added to the list and
;       :  completion can be signalled by I2C communications.
;------------------------------------------------------------------------------

; constants

$const maxword        31;

; coefficients

$const zero           0;
$const 1_2            1;
$const 1_4            2;
$const 1_8            3;
$const sca            4;
$const off            5;
$const linecountcoef  6;

; line memories

$const accu           -1; 

$const input          0;
$const output         1;

$const arg0          0;
$const arg1          1;
$const arg2          2;

$const sobely_preprev  6;
$const sobely_prev     7;
$const sobely_current  8;

$const sobelx_preprev  9;
$const sobelx_prev     10;
$const sobelx_current  11;

$const interpolate_prev 12;
$const interpolate_current 13;

$const captured       14;
$const processed      15;

$const ADC            16;
  
$const res_r          16;
$const res_g          17;
$const res_b          18;

; i2c communication registers

$const task_in_io     PREG0;
$const task_in_type   PREG1;
$const task_in_nr     PREG2;
$const task_out_fin   PREG3;

$const end_row        PREG4;
$const vert_blank     PREG12;

; control processor registers

$const task0_type     REG0;
$const task0_io       REG1;

$const task1_type     REG2;
$const task1_io       REG3;

$const task2_type     REG4;
$const task2_io       REG5;

$const task3_type     REG6;
$const task3_io       REG7;

$const task4_type     REG8;
$const task4_io       REG9;

$const task5_type     REG10;
$const task5_io       REG11;

$const task6_type     REG12;
$const task6_io       REG13;

$const task_nr        REG17;
$const task_type      REG18;
$const task_io        REG19;

$const temp           REG20;
$const temp2          REG21;
$const temp3          REG22;

$const num_blanking   REG23;
$const max_row        REG24;
$const linecount      REG25;

$const   contr_reg    REG27;

$begin

              SETCOEF  zero, 0;
              SETCOEF  1_2, 255;
              SETCOEF  1_4, 127;
              SETCOEF  1_8, 63;
              SETCOEF  sca, 511;
              SETCOEF  off, 511;

              LOADI    contr_reg,1;              start synchroniser
              ORI      contr_reg,8;              set start sensor interface
              ANDI     contr_reg,2039;           reset start sensor interface
              ORI      contr_reg,16;             start serial processor

; *** initialize ***

              LOADI    task_nr, maxword;
              OUTPAR   task_in_nr, task_nr;
              LOADI    max_row, 0;
              
; *** task scheduler ***

; communication
@SCHEDULE:    INPAR    task_nr, task_in_nr;      Check for communication
              COMPI    task_nr, maxword;
              JUMPE    CAPTURE;

; capturing
@CAPTURE:     COMPI    num_blanking, 0;          check for blanking
              JUMPG    DISPLAY;
              COMP     linecount, max_row;       check for capturing
              JUMPL    DOCAPTURE;
              
              INPAR    max_row, end_row;         start capturing              
              LOADI    linecount, 0;
              ORI      contr_reg, 4;             set active_region
@DOCAPTURE:   INC      linecount, 1;             capture a line
              WAITLINE;
              NOP;
              PASS     accu, ADC(0);
              ADD      captured(0), off;
              PASS     accu, ADC(1);
              ADD      captured(1), off;

; process
              PASS     processed(0), zero;
              PASS     processed(1), zero;
              COMPI    task_nr, 0;
              JUMPE    DISPLAY;
              PASS     processed(0), 1_2;
              PASS     processed(1), 1_2;

; display
@DISPLAY:     COMPI    num_blanking, 0;          check for blanking
              JUMPG    DOBLANKING;
              
@DODISPLAY:   PASS     res_r(0), processed(0);
              PASS     res_r(1), processed(1);
              ORI      contr_reg, 2;             set output line trigger
              ANDI     contr_reg, 2045;          reset output line trigger

              COMP     linecount, max_row;       check for vertical blanking
              JUMPL    SCHEDULE;

              INPAR    num_blanking, vert_blank; start blanking
              ANDI     contr_reg, 2043;          reset active_region
@DOBLANKING:  COMPI    num_blanking, 0;
              JUMPE    SCHEDULE;
              WAITLINE;
              NOP;
              DEC      num_blanking, 1;
              JUMP     SCHEDULE;

$end
